﻿using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using BLL.DbAccess;
using BLL.Installer;
using BLL.Interface.User;
using BLL.Model.Base;
using BLL.Model.User;
using BLL.Utility;
using Castle.Core.Logging;

namespace BLL.Implement.User
{
    public class UserInfoImpl : IUserInfo
    {
        public ILogger Logger { get; set; }
        private readonly DefaultContext _defaultContext;
        private readonly DbSet<UserInfo> _userInfoContext;

        public UserInfoImpl()
        {
            _defaultContext = ContainerHelper.Instance.Container.Resolve<DefaultContext>();
            _userInfoContext = _defaultContext.UserInfoContext;
        }

        public bool AddUserInfo(UserInfo userInfo)
        {
            userInfo.Password = EncryptPassword(userInfo.Password);
            foreach (var roleInfo in userInfo.RoleList)
            {
                _defaultContext.RoleInfoContext.Attach(roleInfo);
            }
            _userInfoContext.Add(userInfo);
            _defaultContext.SaveChanges();
            Logger.InfoFormat("新增了一条记录：{0}", userInfo);
            return true;
        }

        public bool UpdateUserInfo(UserInfo userInfo)
        {
            var user = FindUserInfoById(userInfo.Id);
            CopyProperties.Compare(user, userInfo, new List<string> { "Id", "RoleList" });
            //update roleinfo
            var roleName = user.IsAdmin ? "admin" : "user";
            var role = _defaultContext.RoleInfoContext.First(p => p.Name == roleName);
            user.RoleList.Clear();
            user.RoleList.Add(role);

            _defaultContext.SaveChanges();
            Logger.InfoFormat("更新了一条记录：{0}", user);
            return true;
        }

        public bool DeleteUserInfoById(int id)
        {
            var userInfo = FindUserInfoById(id);
            if (userInfo == null)
            {
                Logger.InfoFormat("删除失败：没有找到编号为{0}的记录", id);
                return false;
            }
            _userInfoContext.Remove(userInfo);
            _defaultContext.SaveChanges();
            Logger.InfoFormat("删除了一条记录：{0}", userInfo);
            return true;
        }

        public IList<UserInfo> GetAllUserInfo()
        {
            return _userInfoContext.AsNoTracking().ToList();
        }

        public UserInfo FindUserInfoById(int id)
        {
            return _userInfoContext.Find(id);
        }

        public UserInfo FindUserInfoByAccountName(string accountName)
        {
            return _userInfoContext.AsNoTracking().FirstOrDefault(p => p.AccountName == accountName);
        }

        public IList<UserInfo> GetUserInfoByFilter(dynamic condition, Tuple<string, string> sort, PageInfo page)
        {
            var query = _userInfoContext.AsQueryable();

            query = HandleCondition(condition, query);

            query = HandleSort(sort, query);

            if (page != null)
            {
                page.TotalRecords = query.Count();
                return query.Skip(page.PageSize * (page.CurrentPage - 1))
                           .Take(page.PageSize).ToList();
            }
            return query.ToList();
        }

        private static IQueryable<UserInfo> HandleCondition(dynamic condition, IQueryable<UserInfo> query)
        {
            if (!string.IsNullOrWhiteSpace(condition.AccountName))
            {
                string temp = condition.AccountName;
                query = query.Where(p => p.AccountName.Contains(temp));
            }
            if (!string.IsNullOrWhiteSpace(condition.UserName))
            {
                string temp = condition.UserName;
                query = query.Where(p => p.UserName.Contains(temp));
            }
            return query;
        }

        private static IQueryable<UserInfo> HandleSort(Tuple<string, string> sort, IQueryable<UserInfo> query)
        {
            var orderByRole = false;
            if (sort == null || string.IsNullOrWhiteSpace(sort.Item1) || string.IsNullOrWhiteSpace(sort.Item2))
            {
                sort = new Tuple<string, string>("Id", "asc");
            }
            else if (sort.Item1 == "Role")
            {
                orderByRole = true;
                query = sort.Item2 == "asc"
                            ? query.OrderBy(p => p.RoleList.OrderBy(r => r.Name).FirstOrDefault().Name)
                            : query.OrderByDescending(p => p.RoleList.OrderBy(r => r.Name).FirstOrDefault().Name);
            }

            if (!orderByRole)
            {
                query = query.OrderBy(sort.Item1, sort.Item2);
            }
            return query;
        }

        public LoginUserInfo CheckUser(string accountName, string password)
        {
            password = EncryptPassword(password);
            var user = _userInfoContext.AsNoTracking().FirstOrDefault(p => p.AccountName == accountName && p.Password == password);
            if (user != null)
            {
                var result = new LoginUserInfo
                                 {
                                     UserInfoId = user.Id,
                                     UserAccountName = user.AccountName,
                                     UserName = user.UserName,
                                     Roles = user.RoleList.Select(p => p.Name).ToList()
                                 };
                return result;
            }
            return null;
        }

        public bool CheckAccountNameExists(string accountName)
        {
            return _userInfoContext.Count(p => p.AccountName == accountName) > 0;
        }

        public bool ResetPassword(int id, string newPassword)
        {
            var user = FindUserInfoById(id);
            user.Password = EncryptPassword(newPassword);
            _defaultContext.SaveChanges();
            Logger.InfoFormat("修改密码，用户：{0}", user);
            return true;
        }

        public bool AddUserInfo(IList<UserInfo> userInfoList)
        {
            throw new NotImplementedException();
        }

        public bool DeleteUserInfoById(IList<int> userInfoList)
        {
            try
            {
                foreach (int id in userInfoList)
                {
                    var entryToDelete = FindUserInfoById(id);
                    _userInfoContext.Remove(entryToDelete);
                }
                int count = _defaultContext.SaveChanges();
                Logger.InfoFormat("{0}条记录被删除。", count);
                return true;
            }
            catch (Exception ex)
            {
                Logger.Error(ex.Message);
                return false;
            }
        }

        private static string EncryptPassword(string password)
        {
            return EncryptHelper.SHA(password);
        }

    }

}
